home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / support / mktemp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-24  |  2.4 KB  |  108 lines

  1. /*
  2.  * Copyright (c) 1987 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #if defined(LIBC_SCCS) && !defined(lint)
  19. static char sccsid[] = "@(#)mktemp.c    5.7 (Berkeley) 6/27/88";
  20. #endif /* LIBC_SCCS and not lint */
  21.  
  22. #include <sys/types.h>
  23. #include <sys/file.h>
  24. #include <sys/stat.h>
  25. #include <errno.h>
  26. #include <stdio.h>
  27. #include <ctype.h>
  28.  
  29. #define    YES    1
  30. #define    NO    0
  31.  
  32. mkstemp(as)
  33.     char    *as;
  34. {
  35.     int    fd;
  36.  
  37.     return (_gettemp(as, &fd) ? fd : -1);
  38. }
  39.  
  40. char *
  41. mktemp(as)
  42.     char    *as;
  43. {
  44.     return(_gettemp(as, (int *)NULL) ? as : (char *)NULL);
  45. }
  46.  
  47. static
  48. _gettemp(as, doopen)
  49.     char    *as;
  50.     register int    *doopen;
  51. {
  52.     extern int    errno;
  53.     register char    *start, *trv;
  54.     struct stat    sbuf;
  55.     u_int    pid;
  56.  
  57.     pid = getpid();
  58.  
  59.     /* extra X's get set to 0's */
  60.     for (trv = as; *trv; ++trv);
  61.     while (*--trv == 'X') {
  62.         *trv = (pid % 10) + '0';
  63.         pid /= 10;
  64.     }
  65.  
  66.     /*
  67.      * check for write permission on target directory; if you have
  68.      * six X's and you can't write the directory, this will run for
  69.      * a *very* long time.
  70.      */
  71.     for (start = ++trv; trv > as && *trv != '/'; --trv);
  72.     if (*trv == '/') {
  73.         *trv = '\0';
  74.         if (stat(as, &sbuf) || !(sbuf.st_mode & S_IFDIR))
  75.             return(NO);
  76.         *trv = '/';
  77.     }
  78.     else if (stat(".", &sbuf) == -1)
  79.         return(NO);
  80.  
  81.     for (;;) {
  82.         if (doopen) {
  83.             if ((*doopen = open(as, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
  84.             return(YES);
  85.             if (errno != EEXIST)
  86.             return(NO);
  87.         }
  88.         else if (stat(as, &sbuf))
  89.             return(errno == ENOENT ? YES : NO);
  90.  
  91.         /* tricky little algorithm for backward compatibility */
  92.         for (trv = start;;) {
  93.             if (!*trv)
  94.                 return(NO);
  95.             if (*trv == 'z')
  96.                 *trv++ = 'a';
  97.             else {
  98.                 if (isdigit(*trv))
  99.                     *trv = 'a';
  100.                 else
  101.                     ++*trv;
  102.                 break;
  103.             }
  104.         }
  105.     }
  106.     /*NOTREACHED*/
  107. }
  108.